package com.zsrt.javaweb.bbu.book.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.zsrt.javaweb.bbu.book.dao.BookShopDao;
import com.zsrt.javaweb.bbu.book.service.BookShopService;

@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService {
	
	@Autowired
	private BookShopDao bookShopDao;

	
	/**
	 * 1：使用propagation指定事务的传播行为：即当前的事务方法被另外一个事务方法调用时。如何使用事务
	 * 事务的传播行为默认就是： propagation=Propagation.REQUIRED  [简单说 有事务就行]
	 * 
	 * propagation=Propagation.REQUIRES_NEW 成功1个算1个 [2兄弟建房子 老大有30万 老二有20万 都想建1栋3层楼的房子要30万。如果2个一起建立。那么可以成功REQUIRED。如果分开建。老大成功，老二不成功。REQUIRES_NEW]
	 * 
	 * 2：使用isolation指定事务的隔离级别 最常用的取值为isolation=Isolation.READ_COMMITTED
	 * 
	 * 3：默认情况下Spring的声明式事务 对所有的运行时异常进行回滚 也可以通过[noRollbackFor来设置对哪些异常不回滚] 通常情况下取默认值
	 * 
	 * 4: 使用readOnly指定事务是否为只读。[也就是说读取数据的时候没必要加锁 但是写数据的时候必须加锁 提高查询的效率]
	 * 只读事务属性：表明这个事务只读取数据但不更新数据。这样可以帮助数据库引擎优化事务。
	 * 
	 * 5：timeout 超时事务属性：事务在强制回滚之前可以保持多久。这样可以防止长期运行的事务占用资源。单位为秒
	 * 
	 */
	//@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED,noRollbackFor={UserAccountException.class})
	@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED,readOnly=false,timeout=3)
	@Override
	public void purchase(String username, int isbn) {
		
		
		try {
			
			//单位 毫秒
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		//1 获取书的单价
		int price = bookShopDao.findBookPriceByIsbn(	isbn);
		
		//2 更新书的库存  -1
		bookShopDao.updateBookStock(	isbn);
		
		//3 更新用户余额  
		bookShopDao.updateUserAccount(username, price);

	}

}
